package com.maiji.cloud.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Maps;
import com.maiji.cloud.config.MyRedisConfig;
import com.maiji.cloud.entities.login.AppUser;
import com.maiji.cloud.entities.login.UploadRecord;
import com.maiji.cloud.entities.login.UserInfo;
import com.maiji.cloud.entities.shopingmall.*;
import com.maiji.cloud.listener.AsyncService;
import com.maiji.cloud.mapper.*;
import com.maiji.cloud.microservice.UploadRecordService;
import com.maiji.cloud.microservice.UserInfoService;
import com.maiji.cloud.request.BaseDataReqDto;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.request.shopingmall.*;
import com.maiji.cloud.request.shopingmall.PayResDto;
import com.maiji.cloud.response.*;
import com.maiji.cloud.response.shopingmall.*;
import com.maiji.cloud.response.shopingmall.AliPayResData.AliPayResInner;
import com.maiji.cloud.response.shopingmall.FinancialDetailsResDto.FinancialDetailsResObject;
import com.maiji.cloud.service.*;
import com.maiji.cloud.utils.*;

import com.alibaba.fastjson.JSON;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class CapitalMainLogServiceImpl extends ServiceImpl<CapitalMainLogMapper, CapitalMainLog> implements CapitalMainLogService {
	Logger logger = LoggerFactory.getLogger(CapitalMainLogServiceImpl.class);
	
	@Autowired
	private TaskMapper taskMapper;
	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserInfoService userInfoService;
	@Autowired
	private CapitalMainLogMapper capitalMainLogMapper;
	@Autowired
	private ExchangeLogMapper exchangeLogMapper;
	@Lazy
	@Autowired
	private AsyncService asyncService;
	@Autowired
	private ShopingCartMapper shopingCartMapper;
	@Autowired
	private CapitalIOMapper capitalIOMapper;
    @Autowired
    private CapitalIOService capitalIOService;
	@Autowired
	private CapitalMainService capitalMainService;
	@Autowired
	private CapitalMainMapper capitalMainMapper;
	@Autowired
	private ShopingOrderMapper shopingOrderMapper;
	@Autowired
	private ShopingOrderService shopingOrderService;
	@Autowired
	private DistributionService distributionService;
	@Autowired
	private GoodsMapper goodsMapper;
	@Autowired
	private ShareOrderLogMapper shareOrderLogMapper ;
	@Autowired
	private UploadRecordService uploadRecordService;
	@Autowired
	private ShoppingOrderRefundMapper shoppingOrderRefundMapper;
	@Autowired
	private ShopingOrderMiddleShopingCartMapper shopingOrderMiddleShopingCartMapper;
	@Autowired
	private ShopingOrderRefundService shopingOrderRefundService;
	@Autowired
	private ShareOrderLogService shareOrderLogService;
	@Autowired
	private BindWithdrawAccountMapper bindWithdrawAccountMapper;
	@Autowired
	private WithdrawApplyService withdrawApplyService;

	public FinancialDetailsResDto financialDetails(ReqMetaData param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.financialDetails,param is {}", JSON.toJSONString(param));
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.financialDetails,appUser is {}", JSON.toJSONString(appUser));
			FinancialDetailsResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}
		Integer start = (param.getPage() - 1) * param.getSize();

		List<CapitalMainLog> list = capitalMainLogMapper.getCapitalMainLogListByUserId(null,
				CommonIntValueEnum.CAPITAL_TYPE_MONEY.getValue(), null,appUser.getUuId(), null,null,start, param.getSize());
		List<FinancialDetailsResData> listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>();

		for (CapitalMainLog capitalMainLog : list) {
			FinancialDetailsResData financialDetailsResData = new FinancialDetailsResData();
			BeanUtils.copyProperties(capitalMainLog, financialDetailsResData);
			financialDetailsResData.setRemark(FlowTypeEnum.getMsg(capitalMainLog.getRemark()));
			List<String> goodNames = new ArrayList<String>();
			if (FlowTypeEnum.ORDER_SUBMIT.getKey().equals(capitalMainLog.getRemark())
					|| FlowTypeEnum.ORDER_CANCEL.getKey().equals(capitalMainLog.getRemark())
					|| FlowTypeEnum.ORDER_SUBMIT.getKey().equals(capitalMainLog.getRemark())) {
				List<ShopingCartResData> listShopingCart = shopingCartMapper
						.selectListByOrderId(capitalMainLog.getRelevantId());
				goodNames = listShopingCart.stream().map(shopingCart -> {
					GoodsResData goodsById = goodsMapper.findGoodsById(shopingCart.getUuId());
					return goodsById.getName();
				}).collect(Collectors.toList());
				financialDetailsResData.setGoodsNames(goodNames);
			}

			if (capitalMainLog.getRemark() == FlowTypeEnum.WITHDRAW.getKey()) {
				goodNames.add(FlowTypeEnum.getMsg(capitalMainLog.getRemark()));
			}
			listFinancialDetailsResData.add(financialDetailsResData);
		}

		FinancialDetailsResDto financialDetailsResDto = new FinancialDetailsResDto(Status.SUCCESS);
		FinancialDetailsResObject financialDetailsResObject = financialDetailsResDto.dataInstance();
		financialDetailsResObject.setList(listFinancialDetailsResData);
		// 充值金额
		Double recharge = capitalIOMapper.selectSumByUserId(appUser.getUuId(),
				CommonIntValueEnum.CAPITAL_TYPE_IN.getValue());
		// 提现金额
		Double drawMoney = capitalIOMapper.selectSumByUserId(appUser.getUuId(),
				CommonIntValueEnum.CAPITAL_TYPE_OUT.getValue());

		financialDetailsResObject.setDrawSumMoney(drawMoney);
		financialDetailsResObject.setRechargeSumMoney(recharge);
		financialDetailsResDto.setData(financialDetailsResObject);

		return financialDetailsResDto;
	}

	@Override
	public IntegralFlowResDto integralFlow(ReqMetaData param, String maijiToken) {
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.integralFlow,appUser is {}", JSON.toJSONString(appUser));
			FinancialDetailsResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		/*
		 * Integer start = (param.getPage() - 1) * param.getSize();
		 *
		 * List<CapitalMainLog> list =
		 * capitalMainLogMapper.getCapitalMainLogListByUserId(
		 * CommonIntValueEnum.CAPITAL_TYPE_INTEGRAL.getValue(), appUser.getUuId(),
		 * start, param.getSize()); List<FinancialDetailsResData>
		 * listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>(); for
		 * (CapitalMainLog capitalMainLog : list) { FinancialDetailsResData
		 * financialDetailsResData = new FinancialDetailsResData();
		 * BeanUtils.copyProperties(capitalMainLog, financialDetailsResData);
		 * financialDetailsResData.setRemark(FlowTypeEnum.getMsg(capitalMainLog.
		 * getRemark())); listFinancialDetailsResData.add(financialDetailsResData);
		 *
		 * }
		 */

		IntegralFlowResDto financialDetailsResDto = new IntegralFlowResDto(Status.SUCCESS);

//		financialDetailsResDto.setData(listFinancialDetailsResData);

		return financialDetailsResDto;

	}

	@Override
	public CapitalIOListResDto getcapitalIOList(BaseDataReqDto<CapitalIOListReqData> param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.getcapitalIOList,param is {}", JSON.toJSONString(param));
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) CapitalIOListResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		Integer start = (param.getMetaData().getPage() - 1) * param.getMetaData().getSize();
		List<CapitalIOEntity> listCapitalIOEntity = capitalIOMapper.selectListByUserId(appUser.getUuId(),
                CommonIntValueEnum.CAPITAL_TYPE_OUT.getValue(), param.getData().getType(),
                param.getData().getStartTime(), param.getData().getEndTime(),start, param.getMetaData().getSize());
		List<CapitalIOListResData> listCapitalIOListResData = new ArrayList<CapitalIOListResData>();
		for (CapitalIOEntity capitalIOEntity : listCapitalIOEntity) {
			CapitalIOListResData capitalIOListResData = new CapitalIOListResData();
			BeanUtils.copyProperties(capitalIOEntity, capitalIOListResData);
			listCapitalIOListResData.add(capitalIOListResData);
		}
		CapitalIOListResDto capitalIOListResDto = new CapitalIOListResDto(Status.SUCCESS);
		capitalIOListResDto.setCapitalIOListResData(listCapitalIOListResData);
		return capitalIOListResDto;
	}

	@Override
	public BaseDataResDto<Map<String, Object>> weixinPay(WeixinPayReqDto param, String maijiToken) throws Exception {
		logger.info("CapitalMainLogServiceImpl.weixinPay,param is {}", JSON.toJSONString(param));
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) return new BaseDataResDto<>(Status.PARAMETERERROR);
		// 根据订单号查看订单是否存在
		ShopingOrder shopingOrder = new ShopingOrder();
		shopingOrder.setOrderNo(param.getData().getOut_trade_no());
		ShopingOrder newShopingOrder = shopingOrderMapper.selectOne(shopingOrder);
		if (newShopingOrder == null) return new BaseDataResDto<>(Status.PARAMETERERROR, "订单编号不存在");
		// 校验支付金额和应付金额是否一致
		if (param.getData().getTotalMoney() != newShopingOrder.getAmount()) {
			logger.info("CapitalMainLogServiceImpl.weixinPay,支付金额  {}，应付金额 {}", param.getData().getTotalMoney(), shopingOrder.getAmount());
			return new BaseDataResDto<>(Status.PARAMETERERROR, "支付金额错误");
		}

		String out_trade_no = shopingOrder.getOrderNo() + "_" + (int) (Math.random() * 1000000);
		Map map = new HashMap();
		map.put("appid", WXUtil.APP_ID);
		map.put("mch_id", WXUtil.MCH_ID);
		map.put("nonce_str", UUID_MD5.getUUID());
		map.put("sign_type", "MD5");
		map.put("body", "麦吉-商品支付");
		map.put("out_trade_no", out_trade_no);
		map.put("fee_type", "CNY");
		map.put("total_fee", (int) (param.getData().getTotalMoney() * 100) + "");
		map.put("spbill_create_ip", "192.168.100.8");
		map.put("notify_url", WXUtil.NOTIFY_URL);
		map.put("trade_type", "APP");
		map.put("sign", WXPayUtil.MD5(WXUtil.createSign(map)).toUpperCase());
		logger.info("CapitalMainLogServiceImpl.weixinPay 请求微信预支付参数为  {}", JSON.toJSONString(map));
		// 请求报文
		String data = WXPayUtil.mapToXml(map);
		BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager();
		HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connManager).build();
		String url = (new StringBuilder()).append("https://").append("api.mch.weixin.qq.com").append("/pay/unifiedorder").toString();
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
		httpPost.setConfig(requestConfig);
		StringEntity postEntity = new StringEntity(data, "UTF-8");
		httpPost.addHeader("Content-Type", "text/xml");
		httpPost.addHeader("User-Agent", (new StringBuilder()).append(WXPayConstants.USER_AGENT).append(" ").append(map.get("mch_id")).toString());
		httpPost.setEntity(postEntity);
		HttpResponse httpResponse = httpClient.execute(httpPost);
		org.apache.http.HttpEntity httpEntity = httpResponse.getEntity();
		String reponseString = EntityUtils.toString(httpEntity, "UTF-8");
        logger.info("CapitalMainLogServiceImpl.weixinPay 预支付返回参数 reponseString is {}", reponseString);
		Map mapResponse = WXPayUtil.xmlToMap(reponseString);
		BaseDataResDto paramMap = new BaseDataResDto(Status.SUCCESS);

		Map<String, String> mapWeixinPay = new HashMap<String, String>();
		if (mapResponse.get("return_code") != null && mapResponse.get("result_code") != null) {
			mapWeixinPay.put("appid", WXUtil.APP_ID);
			mapWeixinPay.put("partnerid", WXUtil.MCH_ID);
			if(mapResponse.get("prepay_id") == null) return new BaseDataResDto<>(Status.PARAMETERERROR);
			long time = System.currentTimeMillis() / 1000;
			mapWeixinPay.put("noncestr", Long.toString(time));
			mapWeixinPay.put("timestamp", Long.toString(time));
			mapWeixinPay.put("prepayid", (String) mapResponse.get("prepay_id"));
			mapWeixinPay.put("package", "Sign=WXPay");
			String signString = WXUtil.createSign(mapWeixinPay);
			String signs = WXPayUtil.MD5(signString).toUpperCase();
			mapWeixinPay.put("sign", signs);
			paramMap.setData(mapWeixinPay);
			newShopingOrder.setPrepayId((String) mapResponse.get("prepay_id"));
			newShopingOrder.setNonceStr(map.get("nonce_str") + "");
		} else paramMap.setStatus(Status.PARAMETERERROR);
        // 保存预支付订单号
        shopingOrderMapper.updateById(newShopingOrder.setOutTradeNo(out_trade_no));
		return paramMap;
	}

    @Override
    public BaseDataResDto<Map<String, Object>> weixiAppletPay(WeixinPayReqDto param, String maijiToken) throws Exception {
        logger.info("CapitalMainLogServiceImpl.weixiAppletPay,param is {}", JSON.toJSONString(param));
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        if (appUser == null) {
            logger.info("CapitalMainLogServiceImpl.weixiAppletPay,appUser is {}", JSON.toJSONString(appUser));
            return new BaseDataResDto<>(Status.PARAMETERERROR);
        }

        // 根据订单号查看订单是否存在
        ShopingOrder shopingOrder = new ShopingOrder();
        shopingOrder.setOrderNo(param.getData().getOut_trade_no());
        ShopingOrder newShopingOrder = shopingOrderMapper.selectOne(shopingOrder);
        if (newShopingOrder == null) {
            return new BaseDataResDto<Map<String, Object>>(Status.PARAMETERERROR, "订单编号不存在");
        }
        // 校验支付金额和应付金额是否一致
        if (param.getData().getTotalMoney() != newShopingOrder.getAmount()) {
            logger.info("CapitalMainLogServiceImpl.weixinPay,支付金额  {}，应付金额 {}", param.getData().getTotalMoney(), shopingOrder.getAmount());
            return new BaseDataResDto<Map<String, Object>>(Status.PARAMETERERROR, "支付金额错误");
        }

        String out_trade_no = shopingOrder.getOrderNo() + "_" + (int) (Math.random() * 1000000);
        Map map = new HashMap();
        map.put("appid", WXUtil.APPLET_APP_ID);
        map.put("mch_id", WXUtil.MCH_ID);
        map.put("nonce_str", UUID_MD5.getUUID());
        map.put("sign_type", "MD5");
        map.put("body", "麦吉-商品支付");
        map.put("out_trade_no", out_trade_no);
        map.put("fee_type", "CNY");
        int total_fee = (int) (param.getData().getTotalMoney() * 100);
        map.put("total_fee", total_fee + "");
        map.put("spbill_create_ip", "192.168.100.8");
        map.put("notify_url", WXUtil.NOTIFY_URL);
        map.put("trade_type", "JSAPI");
        map.put("openid", param.getData().getOpenid());

        String paySignString = WXUtil.createSign(map);

        String sign = WXPayUtil.MD5(paySignString).toUpperCase();
        map.put("sign", sign);
        logger.info("CapitalMainLogServiceImpl.weixiAppletPay 请求微信预支付参数为  {}", JSON.toJSONString(map));
        // 请求报文
        String data = WXPayUtil.mapToXml(map);
        BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager();
        HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connManager).build();
        String url = (new StringBuilder()).append("https://").append("api.mch.weixin.qq.com").append("/pay/unifiedorder").toString();
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        StringEntity postEntity = new StringEntity(data, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.addHeader("User-Agent", (new StringBuilder()).append(WXPayConstants.USER_AGENT).append(" ").append(map.get("mch_id")).toString());
        httpPost.setEntity(postEntity);
        HttpResponse httpResponse = httpClient.execute(httpPost);
        org.apache.http.HttpEntity httpEntity = httpResponse.getEntity();
        String reponseString = EntityUtils.toString(httpEntity, "UTF-8");
        logger.info("CapitalMainLogServiceImpl.weixiAppletPay 预支付返回参数 reponseString is {}", reponseString);

        Map mapResponse = WXPayUtil.xmlToMap(reponseString);
        BaseDataResDto paramMap = new BaseDataResDto(Status.SUCCESS);

        Map<String, String> mapWeixinPay = new HashMap<String, String>();

        if (mapResponse.get("return_code") != null && mapResponse.get("result_code") != null) {
            mapWeixinPay.put("appId", WXUtil.APPLET_APP_ID);
            long time = System.currentTimeMillis() / 1000;
            mapWeixinPay.put("nonceStr", Long.toString(time));
            mapWeixinPay.put("timeStamp", Long.toString(time));

            mapWeixinPay.put("package", "prepay_id=" + (String) mapResponse.get("prepay_id"));
            mapWeixinPay.put("signType", "MD5");

            String signString = WXUtil.createSign(mapWeixinPay);

            String signs = WXPayUtil.MD5(signString).toUpperCase();
            mapWeixinPay.put("sign", signs);
            paramMap.setData(mapWeixinPay);

            newShopingOrder.setPrepayId((String) mapResponse.get("prepay_id"));
            newShopingOrder.setNonceStr(map.get("nonce_str") + "");
        } else paramMap.setStatus(Status.PARAMETERERROR);

        // 保存预支付订单号
        shopingOrderMapper.updateById(newShopingOrder.setOutTradeNo(out_trade_no));
        return paramMap;
    }

	@Override
	public Map weixinPayCallBack(PayResDto param) {
		logger.info("CapitalMainLogServiceImpl.weixinPayCallBack param is {}", JSON.toJSONString(param));
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("return_code", "SUCCESS");
		if (param == null) {
			logger.info("CapitalMainLogServiceImpl.weixinPayCallBack ,回调参数为空 param is {}", JSON.toJSONString(param));
			map.put("return_msg", "参数为空");
			return map;
		}

		// 根据订单号查看订单信息
        ShopingOrder shopingOrder = shopingOrderService.selectOne(new EntityWrapper<ShopingOrder>()
                .eq("order_no", param.getOut_trade_no().substring(0, 20)));

		// 已经付款
        if (Arrays.asList(1, 2, 3, 5, 6).contains(shopingOrder.getStatus())) {
			map.put("return_msg", "OK");
			return map;
		}

		shopingOrder.setStatus(CommonIntValueEnum.SHOPPING_ORDER_STATUS_STAY_SHIPMENTS.getValue()).setPayId(param.getTransaction_id())
            .setPayDate(new Date()).setOutTradeNo(param.getOut_trade_no()).setPayType(CommonIntValueEnum.SHOPPING_ORDER_PAY_TYPE_WX.getValue());
		
		// 修改支付状态为成功
		shopingOrderMapper.updateById(shopingOrder);

		// 获取购物车记录集合
		EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
		wrapper.eq("order_id", shopingOrder.getUuId());
		List<ShopingOrderMiddleShopingCart> list = shopingOrderMiddleShopingCartMapper.selectList(wrapper);

		List<String> cardIds = list.parallelStream().map(ShopingOrderMiddleShopingCart::getShopingCartId).collect(Collectors.toList());

		// 修改购物车状态为已付款
		shopingCartMapper.updateStatusByIds(cardIds, CommonIntValueEnum.SHOPPING_CART_STATUS_ALLREADY_PAY.getValue());

		distributionService.asyncDistributionFund(shopingOrder);
		map.put("return_msg", "OK");
		return map;
	}

	@Override
	public BaseResDto executeRefund(String orderRefundId) {
		ShoppingOrderRefundEntity shoppingOrderRefund = shopingOrderRefundService.selectById(orderRefundId)
                .setRefundMiddleTime(new Date()).setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_MIDDLE.getValue());
		String orderId = shoppingOrderRefund.getOrderId();
		ShopingOrder shopingOrder = shopingOrderMapper.selectById(orderId)
                .setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_MIDDLE.getValue());
		Double refundManey = shoppingOrderRefund.getRefundManey();
		Double amount = shopingOrder.getAmount();
		if (refundManey > amount) return BaseResDto.baseResDto(Status.ERROR, "退款金额错误！");
		Integer payType = shopingOrder.getPayType();
		if (payType == 2) { // 申请微信退款
			try {
				 Map wxMap = WXUtil.applayRefund(shopingOrder.getUserId(), shopingOrder.getPayId(), shopingOrder.getOutTradeNo(), amount, refundManey);
				 logger.info("CapitalMainLogServiceImpl.executeRefund 微信退款返回参数：{}", JSON.toJSONString(wxMap));
                if (! wxMap.get("result_code").equals("SUCCESS")) return BaseResDto.baseResDto(Status.ERROR, "申请微信退款失败！");
			} catch (Exception e) {
				e.printStackTrace();
				return BaseResDto.baseResDto(Status.ERROR, "申请微信退款失败！");
			}
		}
		if (payType == 3) { // 申请支付宝退款
			try {  // 调用支付宝退款同步返回退款结果
				AlipayTradeRefundResponse response = AlipayUtil.alipayRefund(shopingOrder.getOrderNo(), shopingOrder.getPayId(), refundManey);
				logger.info("CapitalMainLogServiceImpl.executeRefund 支付宝支付返回参数：{}", JSON.toJSONString(response));
			} catch (Exception e) {
				e.printStackTrace();
				return BaseResDto.baseResDto(Status.ERROR, "支付宝退款失败！");
			}
		}
		if (payType == 1) { // 余额支付：将退款金额退回用户订单返现余额
            if (! capitalMainService.updateCapitalMain(shopingOrder.getUserId(), FlowTypeEnum.RETURNMONEY, refundManey.toString(),
                    FlowTypeEnum.INCREASE, FlowTypeEnum.ORDER_REFUND_MONEY, shoppingOrderRefund.getUuId()))
                return BaseResDto.baseResDto(Status.ERROR, "余额支付退款保存用户账户资金流水失败！");
		}
        if (Arrays.asList(1, 3).contains(payType)) {
            shopingOrder.setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue());
            shoppingOrderRefund.setRefundFinishTime(new Date()).setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue());
            // 退回用户订单中使用的减肥基金、积分、优惠券
            asyncService.returnFundIntegralCoupon(shopingOrder.getOrderNo());
            // 追回分销提成
            distributionService.asyncReturnDistributionFund(shopingOrder.getUuId());
        }
        if (! shopingOrderService.updateById(shopingOrder)) return BaseResDto.baseResDto(Status.ERROR, "修改订单退款状态失败！");
        if (! shopingOrderRefundService.updateById(shoppingOrderRefund)) return BaseResDto.baseResDto(Status.ERROR, "修改退款记录退款状态失败！");
        return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseResDto userApplayRefund(UserApplayRefundReqDto param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.userApplayRefund,param is {} ,maijiToken is {}", JSON.toJSONString(param), maijiToken);
		// 退款类型
		int type = param.getData().getType();
		if (!(type == CommonIntValueEnum.SHOPPING_ORDER_REFUND_TYPE_REFUND.getValue()
				|| type == CommonIntValueEnum.SHOPPING_ORDER_REFUND_TYPE_RETURN_GOODS_REFUND.getValue())) {
			logger.info("CapitalMainLogServiceImpl.userApplayRefund,type is {}", type);
			return BaseResDto.baseResDto(Status.PARAMETERERROR, "退款类型错误");
		}

		ShopingOrder shopingOrder = shopingOrderService.selectById(param.getData().getOrderId());
		if (shopingOrder == null) return BaseResDto.baseResDto(Status.PARAMETERERROR, "订单id错误");

		shopingOrder.setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_APPLAY.getValue()).setRefundDate(new Date());
		if (!shopingOrderService.updateById(shopingOrder)) return new BaseResDto(Status.ERROR.setMessage("修改订单退款状态失败"));

		synchronized (CapitalMainLogServiceImpl.class) {
            EntityWrapper<ShoppingOrderRefundEntity> shoppingOrderRefundEntityWrapper = new EntityWrapper<ShoppingOrderRefundEntity>();
            shoppingOrderRefundEntityWrapper.eq("order_id", param.getData().getOrderId());
            ShoppingOrderRefundEntity oldShoppingOrderRefundEntity = shopingOrderRefundService.selectOne(shoppingOrderRefundEntityWrapper);
            //清除之前申请的退款记录
            if(oldShoppingOrderRefundEntity != null) shoppingOrderRefundMapper.deleteById(oldShoppingOrderRefundEntity.getUuId());

            ShoppingOrderRefundEntity shoppingOrderRefundEntity = new ShoppingOrderRefundEntity();
            shoppingOrderRefundEntity.setUuId(UUID_MD5.getUUID());
            shoppingOrderRefundEntity.setOrderId(param.getData().getOrderId());
            shoppingOrderRefundEntity.setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_APPLAY.getValue());
            shoppingOrderRefundEntity.setType(type);
            shoppingOrderRefundEntity.setRefundReason(param.getData().getRefundReason());
            shoppingOrderRefundEntity.setRefundExplain(param.getData().getRefundExplain());
            shoppingOrderRefundEntity.setInTime(new Date());
            shoppingOrderRefundMapper.insert(shoppingOrderRefundEntity);
            if (param.getData().getImgIds() != null && param.getData().getImgIds().size() > 0) {
                List<UploadRecord> uploadRecords = param.getData().getImgIds().stream().map(imgId ->
                        new UploadRecord().setUuId(imgId).setBelongId(shoppingOrderRefundEntity.getUuId())).collect(Collectors.toList());
                // 修改图片表
                if (!uploadRecordService.updateBatchUploadRecord(uploadRecords))
                    return new BaseResDto(Status.ERROR, "修改图片信息出错");
            }
        }

		// 终止订单返现分享助力
		EntityWrapper<ShareOrderLog> entityWrapper = new EntityWrapper<>();
		entityWrapper.eq("order_id", shopingOrder.getUuId());
		ShareOrderLog shareOrderLog = shareOrderLogService.selectOne(entityWrapper);
		if (shareOrderLog != null)
			if (!shareOrderLogService.updateById(shareOrderLog.setTermination(true)))
				return new BaseResDto(Status.ERROR, "终止订单返现分享助力活动失败");

		return BaseResDto.baseResDto(Status.SUCCESS, "请求成功");
	}

	@Override
	public BaseResDto agreeApplyRefund(OrderRefundReqData data) {
		// 修改订单退款状态
		ShopingOrder shopingOrder = shopingOrderService.selectById(data.getOrderId());
		if (shopingOrder == null)
			return new BaseResDto(Status.ERROR.setMessage("订单ID参数错误！"));
		Double amount = shopingOrder.getAmount();
		Double refundManey = data.getRefundManey();
		Boolean returnDeliveryFee = data.getReturnDeliveryFee();
		if (!returnDeliveryFee)
			amount = Arith.subtract(2, amount, shopingOrder.getDeliveryFee());
		if (refundManey > amount)
			return new BaseResDto(Status.ERROR.setMessage("退款金额错误！"));
		if (!shopingOrderService.updateById(shopingOrder.setRefundStatus(data.getStatus())))
			return new BaseResDto(Status.ERROR.setMessage("修改订单退款状态失败！"));
		// 修改订单退款记录数据
		ShoppingOrderRefundEntity shoppingOrderRefund = shopingOrderRefundService.selectById(data.getUuId());
		if (shoppingOrderRefund == null)
			return new BaseResDto(Status.ERROR.setMessage("订单退款记录ID参数错误！"));
		shoppingOrderRefund.setStatus(data.getStatus()).setStayRefundTime(new Date())
				.setRefundManey(data.getRefundManey()).setReturnFund(data.getReturnFund())
				.setReturnIntegral(data.getReturnIntegral()).setReturnCoupon(data.getReturnCoupon())
				.setReturnDeliveryFee(data.getReturnDeliveryFee())
                .setRefusalReason(data.getRefusalReason());
		if (shopingOrderRefundService.updateById(shoppingOrderRefund)) return new BaseResDto(Status.SUCCESS);
        return new BaseResDto(Status.ERROR.setMessage("修改订单退记录失败！"));
	}

	@Override
	public Map refundCallBack(WXRefundReqDto param) throws Exception {
		logger.info("CapitalMainLogServiceImpl.refundCallBack param is {}", JSON.toJSONString(param));
		Map map = new HashMap();
		if (param == null) {
			logger.info("CapitalMainLogServiceImpl.refundCallBack ,回调参数为空 param is {}", JSON.toJSONString(param));
			map.put("return_code", "FAIL");
			map.put("return_msg", "参数为空");
			return map;
		}
		if (!"SUCCESS".equals(param.getReturn_code())) {
			logger.info("CapitalMainLogServiceImpl.refundCallBack ,退款失败 param is {}", JSON.toJSONString(param));
			map.put("return_code", "SUCCESS");
			map.put("return_msg", "ok");
			return map;
		}
		Map signMap = objectToMap(param);
		signMap.remove("return_code");
		signMap.remove("return_msg");
		signMap.remove("appid");
		signMap.remove("mch_id");
		signMap.remove("nonce_str");
		signMap.remove("req_info");
		String refundSignString = WXUtil.createSign(signMap);
		String sign = WXPayUtil.MD5(refundSignString).toUpperCase();
		// 验证签名
		if (!sign.equals(param.getReq_info())) {
			logger.info("CapitalMainLogServiceImpl.refundCallBack ,sign is {}，签名错误 param is {}",
					JSON.toJSONString(param), sign);
			map.put("return_code", "FAIL");
			map.put("return_msg", "签名错误");
		}
		
		// 根据订单号查看订单信息
		String order_no = (String) WXUtil.parseReqInfo(param.getReq_info()).get("out_trade_no");
		ShopingOrder shopingOrder = shopingOrderMapper.selectOne(new ShopingOrder().setOutTradeNo(order_no));
		
		// 已经付款
		if (shopingOrder.getStatus() == CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue()) {
			map.put("return_msg", "OK");
			map.put("return_code", "SUCCESS");
			return map;
		}
		// 修改订单退款状态
		shopingOrder.setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue());
		if (!shopingOrderService.updateById(shopingOrder)) {
			map.put("return_code", "FAIL");
			return map;
		}
		// 修改退款状态
		EntityWrapper<ShoppingOrderRefundEntity> entityWrapper = new EntityWrapper<>();
		entityWrapper.eq("order_id", shopingOrder.getUuId());
		ShoppingOrderRefundEntity shoppingOrderRefund = shopingOrderRefundService.selectOne(entityWrapper);
		shoppingOrderRefund.setRefundFinishTime(new Date())
				.setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue());
		if (!shopingOrderRefundService.updateById(shoppingOrderRefund)) {
			map.put("return_code", "FAIL");
			return map;
		}
		// 退回用户订单中使用的减肥基金、积分、优惠券
		asyncService.returnFundIntegralCoupon(order_no);
		// 追回分销提成
		distributionService.asyncReturnDistributionFund(shopingOrder.getUuId());

		map.put("return_msg", "OK");
		map.put("return_code", "SUCCESS");
		return map;
	}

	public Map objectToMap(Object obj) throws Exception {
		if (obj == null)
			return null;

		Map map = new HashMap();

		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor property : propertyDescriptors) {
			String key = property.getName();
			if (key.compareToIgnoreCase("class") == 0) {
				continue;
			}
			Method getter = property.getReadMethod();
			Object value = getter != null ? getter.invoke(obj) : null;
			map.put(key, value);
		}

		return map;
	}

	@Override
	public BaseDataResDto<AliPayResData> alipay(WeixinPayReqDto param, String maijiToken) throws Exception {
		logger.info("CapitalMainLogServiceImpl.alipay param is {}", JSON.toJSONString(param));
		String nowTime = TimeUtil.date2String(new Date(), null);
		AliPayResData aliPayResData = new AliPayResData();
		aliPayResData.setApp_id(AlipayUtil.APP_ID);
		aliPayResData.setCharset("utf-8");
		aliPayResData.setMethod("alipay.trade.app.pay");
		aliPayResData.setNotify_url(AlipayUtil.NOTIFY_URL);
		aliPayResData.setSign_type("RSA2");
		aliPayResData.setTimestamp(nowTime);
		aliPayResData.setVersion("1.0");
		AliPayResInner aliPayResInner = aliPayResData.dataInstance();
		aliPayResInner.setBody("麦吉商品支付");
		aliPayResInner.setSubject("麦吉商品支付");
		aliPayResInner.setGoods_type("1");// 0—虚拟类商品；1—实物类商品
		aliPayResInner.setOut_trade_no(param.getData().getOut_trade_no());
		aliPayResInner.setProduct_code("QUICK_MSECURITY_PAY");
		aliPayResInner.setTotal_amount(param.getData().getTotalMoney() + "");
		aliPayResData.setBiz_content(aliPayResInner);
		Map paramMap = WXUtil.objectToMap(aliPayResData);
		paramMap.remove("biz_content");
		paramMap.put("biz_content", JSON.toJSON(aliPayResInner));
		String signString = AlipayUtil.createSign(paramMap);
		String sign = AlipaySignature.rsaSign(signString, AlipayUtil.PRIVATE_KEY, "utf-8", "RSA2");
		aliPayResData.setSign(sign);
		paramMap.put("sign", sign);
		aliPayResData.setSignString(AlipayUtil.createSignValues(paramMap));
		BaseDataResDto<AliPayResData> baseDataResDto = new BaseDataResDto<AliPayResData>(Status.SUCCESS);
		baseDataResDto.setData(aliPayResData);
		logger.info("CapitalMainLogServiceImpl.alipay,返回参数  {},签名串为signString is {}", JSON.toJSON(aliPayResData),
				signString);

		/*
		 * AlipayClient alipayClient = new
		 * DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
		 * AlipayUtil.APP_ID, AlipayUtil.PRIVATE_KEY, "json", "utf-8",
		 * AlipayUtil.PUBLIC_KEY, "RSA2");
		 * 
		 * //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		 * AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		 * //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(
		 * model和biz_content同时存在的情况下取biz_content)。
		 * 
		 * 
		 * AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		 * model.setBody("我是测试数据"); model.setSubject("App支付测试Java");
		 * model.setOutTradeNo(param.getData().getOut_trade_no());
		 * model.setTotalAmount(param.getData().getTotalMoney()+"");
		 * model.setProductCode("QUICK_MSECURITY_PAY"); request.setBizModel(model);
		 * request.setNotifyUrl(AlipayUtil.NOTIFY_URL); try {
		 * //这里和普通的接口调用不同，使用的是sdkExecute AlipayTradeAppPayResponse response =
		 * alipayClient.sdkExecute(request);
		 * 
		 * aliPayResData.setSignString(response.getBody().substring(37));
		 * 
		 * //就是orderString 可以直接给客户端请求，无需再做处理。 } catch (AlipayApiException e) {
		 * e.printStackTrace(); }
		 */

		return baseDataResDto;
	}

	@Override
	public Map<String, Object> alipayCallBack(Map<String, String> param) throws Exception {
		logger.info("CapitalMainLogServiceImpl.alipayCallBack param is {}", JSON.toJSONString(param));
		Map<String, Object> map = new HashMap<String, Object>();

		if (!"TRADE_FINISHED".equals(param.get("trade_status")) && !"TRADE_SUCCESS".equals(param.get("trade_status"))) {
			logger.info("CapitalMainLogServiceImpl.alipayCallBack ,支付宝支付成功通知状态 , status is {} ", param.get("trade_status"));
			map.put("SUCCESS", "成功");
			return map;
		}

		logger.info("CapitalMainLogServiceImpl.alipayCallBack ,sign is {},charset{},sign_type{}",
				JSON.toJSONString(param), param.get("charset"), param.get("sign_type"));

		boolean signVerified = AlipaySignature.rsaCheckV1(param, AlipayUtil.PUBLIC_KEY, param.get("charset"),param.get("sign_type")); // 调用SDK验证签名
		
		logger.info("CapitalMainLogServiceImpl.alipayCallBack , signVerified is {}" ,signVerified);

		if (!signVerified) {
			logger.info("CapitalMainLogServiceImpl.alipayCallBack ,sign is {}", JSON.toJSONString(param));
			map.put("ERROR", "签名错误");
			return map;
		}
		// 根据订单号查看订单信息
		ShopingOrder shopingOrder = new ShopingOrder();
		shopingOrder.setOrderNo(param.get("out_trade_no"));
		shopingOrder = shopingOrderMapper.selectOne(shopingOrder);

		// 已经付款
		if (Arrays.asList(1, 2, 3, 5, 6).contains(shopingOrder.getStatus())) {
			map.put("return_msg", "OK");
			return map;
		}

		shopingOrder.setStatus(CommonIntValueEnum.SHOPPING_ORDER_STATUS_STAY_SHIPMENTS.getValue());
		shopingOrder.setPayId(param.get("trade_no"));
		shopingOrder.setPayDate(new Date());
		shopingOrder.setPayType(CommonIntValueEnum.SHOPPING_ORDER_PAY_TYPE_ALIPAY.getValue());
		// 修改支付状态为成功
		shopingOrderMapper.updateById(shopingOrder);

		// 获取购物车记录集合
		EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
		wrapper.eq("order_id", shopingOrder.getUuId());
		List<ShopingOrderMiddleShopingCart> list = shopingOrderMiddleShopingCartMapper.selectList(wrapper);

		List<String> cardIds = list.stream()
				.map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
				.collect(Collectors.toList());

		// 修改购物车状态为已付款
		shopingCartMapper.updateStatusByIds(cardIds, CommonIntValueEnum.SHOPPING_CART_STATUS_ALLREADY_PAY.getValue());

		distributionService.asyncDistributionFund(shopingOrder);
		return map;
	}

    @Override
    public BdXCXResDto<Map<String, Object>> bdXCXCallBack(Map<String, String> param) {
        /*BdXCXResDto<Map<String, Object>> bdXCXResDto = new BdXCXResDto<>(0, "success");
        Map<String, Object> map = Maps.newHashMap();
        map.put("isConsumed", 2);
        try {
            logger.info("CapitalMainLogServiceImpl.bdXCXCallBack param is {}", JSON.toJSONString(param));
            String totalMoney = param.get("totalMoney");
            String tpOrderId = param.get("tpOrderId");
            String rsaSign = param.get("rsaSign");
            if (BooleanUtils.isFalse(NuomiSignature.checkSignWithRsa(totalMoney, tpOrderId, rsaSign))) {
                logger.info("CapitalMainLogServiceImpl.bdXCXCallBack ===>> 签名验证失败");
                map.put("isErrorOrder", 1);
                return bdXCXResDto.setData(map);
            }

            // 根据订单号查看订单信息
            ShopingOrder shopingOrder = shopingOrderService.selectOne(new EntityWrapper<ShopingOrder>().eq("order_no", tpOrderId));

            // 已经付款
            if (Arrays.asList(1, 2, 3, 5, 6).contains(shopingOrder.getStatus())) return bdXCXResDto;

            String orderId = param.get("orderId"); // 百度平台订单ID，存入prepayId
            String userId = param.get("userId"); // 百度用户ID，存入payId
            shopingOrder.setStatus(1).setPayId(userId).setPayDate(new Date());
            shopingOrder.setPayType(CommonIntValueEnum.SHOPPING_ORDER_PAY_TYPE_ALIPAY.getValue());
            // 修改支付状态为成功
            shopingOrderMapper.updateById(shopingOrder);

            // 获取购物车记录集合
            EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
            wrapper.eq("order_id", shopingOrder.getUuId());
            List<ShopingOrderMiddleShopingCart> list = shopingOrderMiddleShopingCartMapper.selectList(wrapper);

            List<String> cardIds = list.stream()
                    .map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
                    .collect(Collectors.toList());

            // 修改购物车状态为已付款
            shopingCartMapper.updateStatusByIds(cardIds, CommonIntValueEnum.SHOPPING_CART_STATUS_ALLREADY_PAY.getValue());

            distributionService.asyncDistributionFund(shopingOrder);
        } catch (Exception e) {
	        e.printStackTrace();
        }*/
        return null;
    }

	@Override
	public BaseMetaResDto<List<ShoppingOrderRefundResData>> findAllOrderRefunds(OrderRefundReqData data, ReqMetaData reqMetaData) {
		Integer pageNo = reqMetaData.getPage();
		Integer pageSize = reqMetaData.getSize();
		Page<ShoppingOrderRefundResData> page = new Page<>(pageNo, pageSize);
		List<ShoppingOrderRefundResData> resData = shoppingOrderRefundMapper.findAllOrderRefunds(data, page);
		ResMetaData resMetaData = new ResMetaData(pageNo, pageSize, page.getTotal());
		return new BaseMetaResDto<List<ShoppingOrderRefundResData>>(Status.SUCCESS).setData(resData).setResMetaData(resMetaData);
	}

	@Override
	public BaseDataResDto<List<Map<Integer, Integer>>> findAllOrderRefundsTypeCount() {
		List<Map<Integer, Integer>> mapTypeCounts = shoppingOrderRefundMapper.findAllOrderRefundsTypeCount();
		return new BaseDataResDto<List<Map<Integer, Integer>>>(Status.SUCCESS).setData(mapTypeCounts);
	}

	@Override
	public BaseResDto confirmReceived(String orderRefundId, String orderId) {
		ShoppingOrderRefundEntity shoppingOrderRefund = new ShoppingOrderRefundEntity().setUuId(orderRefundId)
				.setConfirmReceived(true).setConfirmReceivedTime(new Date())
				.setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_STAY_REFUND.getValue());
		if (!shopingOrderRefundService.updateById(shoppingOrderRefund))
			return new BaseResDto(Status.ERROR.setMessage("修改退款记录确认收货状态失败"));
		ShopingOrder shopingOrder = new ShopingOrder().setUuId(orderId)
				.setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_STAY_REFUND.getValue());
		if (!shopingOrderService.updateById(shopingOrder))
			return new BaseResDto(Status.ERROR.setMessage("修改订单记录的退款状态失败"));
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<String> balancePay(BaseDataReqDto<BalancePayReqData> param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.balancePay param is {}", JSON.toJSONString(param));
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.balancePay,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<>(Status.PARAMETERERROR);
		}
		ShopingOrder shopingOrder = new ShopingOrder();
		shopingOrder.setOrderNo(param.getData().getOut_trade_no());
		shopingOrder = shopingOrderMapper.selectOne(shopingOrder);
		// 已经付款
		if (shopingOrder == null
				|| shopingOrder.getStatus() >= CommonIntValueEnum.SHOPPING_ORDER_STATUS_STAY_SHIPMENTS.getValue()) {
			logger.info("CapitalMainLogServiceImpl.balancePay shopingOrder is {}", JSON.toJSONString(shopingOrder));
			return new BaseDataResDto(Status.ERROR, "订单号不正确");
		}
		CapitalMain capitalMain = capitalMainMapper.selectOneByUserId(shopingOrder.getUserId());
		if (capitalMain == null) {
			capitalMainService.createCapitalMain(shopingOrder.getUserId());
		}
		if (capitalMain == null) {
			return new BaseDataResDto<String>(Status.ERROR, "无资金数据");
		}

        UserInfo userInfo = userInfoService.findUserInfoByUserId(appUser.getUuId());
        if (StringUtils.isBlank(userInfo.getPayPassword()))
            return new BaseDataResDto(Status.PARAMETERERROR, "未设置密码，请先设置密码");
        if (! userInfo.getPayPassword().equals(UUID_MD5.md5Str(param.getData().getPayPassword())))
            return new BaseDataResDto(Status.PARAMETERERROR, "密码错误");

		Double orderMoney = param.getData().getTotalMoney();
		// 返现资金支付
		if (orderMoney > capitalMain.getReturnMoney()) return new BaseDataResDto(Status.ERROR, "资金不足");
        if (!capitalMainService.updateCapitalMain(shopingOrder.getUserId(), FlowTypeEnum.RETURNMONEY, orderMoney.toString(),
                FlowTypeEnum.DECREASE, FlowTypeEnum.BALANCE_PAY, shopingOrder.getUuId()))
            return new BaseDataResDto(Status.ERROR.setMessage("余额支付失败"));

		shopingOrder.setStatus(CommonIntValueEnum.SHOPPING_ORDER_STATUS_STAY_SHIPMENTS.getValue());
		shopingOrder.setPayDate(new Date());
		shopingOrder.setPayType(CommonIntValueEnum.SHOPPING_ORDER_PAY_TYPE_BANLANCE.getValue());
		
		// 修改支付状态为成功
		shopingOrderMapper.updateById(shopingOrder);

		// 获取购物车记录集合
		EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
		wrapper.eq("order_id", shopingOrder.getUuId());
		List<ShopingOrderMiddleShopingCart> list = shopingOrderMiddleShopingCartMapper.selectList(wrapper);

		List<String> cardIds = list.stream()
				.map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
				.collect(Collectors.toList());

		// 修改购物车状态为已付款
		shopingCartMapper.updateStatusByIds(cardIds, CommonIntValueEnum.SHOPPING_CART_STATUS_ALLREADY_PAY.getValue());
		// 异步分发分销基金
		distributionService.asyncDistributionFund(shopingOrder);

		return new BaseDataResDto<String>(Status.SUCCESS);
	}

	@Override
	public BaseResDto userCancelRefund(String orderId) {
		Wrapper<ShoppingOrderRefundEntity> wrapper = new EntityWrapper<ShoppingOrderRefundEntity>().eq("order_id",
				orderId);
		ShoppingOrderRefundEntity shoppingOrderRefund = shopingOrderRefundService.selectOne(wrapper);
		List<Integer> refundStatuses = Arrays.asList(
				CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_MIDDLE.getValue(),
				CommonIntValueEnum.SHOPPING_ORDER_REFUND_STATUS_REFUND_FINISH.getValue());
		if (refundStatuses.contains(shoppingOrderRefund.getStatus()))
			return new BaseResDto(Status.ERROR.setMessage("该退款申请已不可撤销"));
		shoppingOrderRefund.setRefundCancelTime(new Date())
				.setStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_NONE.getValue());
		if (!shopingOrderRefundService.updateById(shoppingOrderRefund))
			return new BaseResDto(Status.ERROR.setMessage("修改退款申请状态失败"));
		ShopingOrder shopingOrder = new ShopingOrder().setUuId(orderId)
				.setRefundStatus(CommonIntValueEnum.SHOPPING_ORDER_REFUND_NONE.getValue());
		if (!shopingOrderService.updateById(shopingOrder))
			return new BaseResDto(Status.ERROR.setMessage("修改订单退款退款状态失败"));
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseResDto withdrawOrderReturn(WithdrawReqData data, String maijiToken) {
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) return new BaseDataResDto<>(Status.TOKENINVALID);
        CapitalIOEntity capitalIOEntity = new CapitalIOEntity().setUuId(UUID_MD5.getUUID()).setIoMoney(data.getMoney())
                .setUserId(appUser.getUuId()).setType(CommonIntValueEnum.CAPITAL_TYPE_OUT.getValue()).setInTime(new Date());
		CapitalMain capitalMain = capitalMainMapper.selectOneByUserId(appUser.getUuId());
        capitalIOEntity.setMoney(Arith.subtract(2, capitalMain.getMoney(), data.getMoney()));
        UserInfo userInfo = userInfoService.findUserInfoByUserId(appUser.getUuId());
        if (StringUtils.isBlank(userInfo.getPayPassword()))
			return new BaseResDto(Status.USER_WORNING_INFO, "未设置密码，请先设置密码");
		if (! userInfo.getPayPassword().equals(UUID_MD5.md5Str(data.getPassword())))
			return new BaseResDto(Status.USER_WORNING_INFO, "支付密码输入有误，请确认后重新输入");
        if (capitalMain.getReturnMoney() < data.getMoney())
            return new BaseResDto(Status.USER_WORNING_INFO, "您的账户余额不足，请确认提现金额的额度是否准确");
        capitalIOEntity.setStart(CommonIntValueEnum.WITHDRAWORDERRETURN.getValue());

        BindWithdrawAccountEntity queryEntity = new BindWithdrawAccountEntity().setUserId(appUser.getUuId());;
        // 支付宝提现
		if (data.getType() == CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_ALIPAY.getValue()) {
            queryEntity.setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_ALIPAY.getValue());
            BindWithdrawAccountEntity bindAlipayAccountEntity = bindWithdrawAccountMapper.selectOne(queryEntity);
            if (bindAlipayAccountEntity == null) return new BaseResDto(Status.PARAMETERERROR, "提现信息不完善");
            try {
                AlipayFundTransToaccountTransferResponse reponse = AlipayUtil.alipayWithdraw(capitalIOEntity.getUuId(),
                    bindAlipayAccountEntity.getRealName(), bindAlipayAccountEntity.getAccount(), data.getMoney());
                logger.info("CapitalMainLogServiceImpl.withdrawOrderReturn ===>> reponse = {}",JSON.toJSONString(reponse));
                if (! "10000".equals(reponse.getCode())) return new BaseResDto(Status.PARAMETERERROR, "提现失败");
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
			capitalIOEntity.setEnd(CommonIntValueEnum.ALIPAY.getDescription());
		}

		// 微信提现
		if (data.getType() == CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_WX.getValue()) {
            queryEntity.setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_WX.getValue());
            BindWithdrawAccountEntity bindAlipayAccountEntity = bindWithdrawAccountMapper.selectOne(queryEntity);
            if (bindAlipayAccountEntity == null) return new BaseResDto(Status.PARAMETERERROR, "提现信息不完善");
            try {
                Map map = WXUtil.wxWithdraw(bindAlipayAccountEntity.getAccount(),bindAlipayAccountEntity.getRealName(),data.getMoney());
                logger.info("CapitalMainLogServiceImpl.withdrawOrderReturn ===>> reponse = {}",JSON.toJSONString(map));
                if(! ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) )
                    return new BaseResDto(Status.PARAMETERERROR, "提现失败");
            } catch (Exception e) {
                e.printStackTrace();
            }
			capitalIOEntity.setEnd(CommonIntValueEnum.WEIXIN.getDescription());
		}

        capitalMain.setMoney(NumberUtil.sub(capitalMain.getMoney(), data.getMoney()))
                .setReturnMoney(NumberUtil.sub(capitalMain.getReturnMoney(), data.getMoney()));
        if (! capitalMainService.updateById(capitalMain)) return new BaseResDto(Status.ERROR.setMessage("修改用户资金账户失败"));

        if (! capitalIOService.insert(capitalIOEntity)) return new BaseResDto(Status.ERROR.setMessage("保存用户提现流水失败"));
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseResDto withdrawDistribution(WithdrawReqData data, String maijiToken) {
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) return new BaseDataResDto<>(Status.PARAMETERERROR);
        WithdrawApply withdrawApply = new WithdrawApply().setUuId(UUID_MD5.getUUID()).setUserId(appUser.getUuId())
                .setCapitalIoId(UUID_MD5.getUUID()).setApplyDate(new Date()).setExamine(0);

		CapitalMain capitalMain = capitalMainMapper.selectOneByUserId(appUser.getUuId());
        withdrawApply.setIoMoney(data.getMoney()).setMoney(Arith.subtract(2, capitalMain.getDistributionMoney(), data.getMoney()));
        UserInfo userInfo = userInfoService.findUserInfoByUserId(appUser.getUuId());
        if (StringUtils.isBlank(userInfo.getPayPassword()))
			return new BaseResDto(Status.USER_WORNING_INFO, "未设置密码，请先设置密码");
		if (! userInfo.getPayPassword().equals(UUID_MD5.md5Str(data.getPassword())))
			return new BaseResDto(Status.USER_WORNING_INFO, "支付密码输入有误，请确认后重新输入");

        // 获取分销账户最低提现金额
        Query query = new Query(Criteria.where("type").is(CommonIntValueEnum.WITHDRAWAL_AMOUNT_LIMIT_CONFIG_TYPE_LESS_LEAST.getValue()));
        WithdrawalAmountLimitConfigEntity withdrawalAmountLimitConfigEntity = mongoTemplate.findOne(query,
                WithdrawalAmountLimitConfigEntity.class, WithdrawalAmountLimitConfigEntity.TABLE_NAME);
        if(withdrawalAmountLimitConfigEntity != null && withdrawalAmountLimitConfigEntity.getAmount() > data.getMoney())
            return new BaseResDto(Status.USER_WORNING_INFO, "可提现最低金额为"
                    + withdrawalAmountLimitConfigEntity.getAmount() + "元，请赚取足够的金额后再来提现哦~");
        withdrawApply.setStart(CommonIntValueEnum.WITHDRAWDISTRIBUTION.getValue() + "");
        if (capitalMain.getDistributionMoney() < data.getMoney())
            return new BaseResDto(Status.USER_WORNING_INFO, "您的账户余额不足，请确认提现金额的额度是否准确");

        BindWithdrawAccountEntity bindAlipayAccountEntity = null;
        BindWithdrawAccountEntity queryEntity = new BindWithdrawAccountEntity().setUserId(appUser.getUuId());;
        // 支付宝提现
		if (data.getType() == CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_ALIPAY.getValue()) {
            queryEntity.setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_ALIPAY.getValue());
			bindAlipayAccountEntity = bindWithdrawAccountMapper.selectOne(queryEntity);
            withdrawApply.setEnd(CommonIntValueEnum.ALIPAY.getValue() + "")
                    .setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_ALIPAY.getValue());
		}

		// 微信提现
		if (data.getType() == CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_WX.getValue()) {
            queryEntity.setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_WX.getValue());
			bindAlipayAccountEntity = bindWithdrawAccountMapper.selectOne(queryEntity);
            withdrawApply.setEnd(CommonIntValueEnum.WEIXIN.getValue() + "")
                    .setType(CommonIntValueEnum.BIND_WITHDRAW_ACCOUNT_TYPE_WX.getValue());
		}

        if (bindAlipayAccountEntity == null) return new BaseResDto(Status.PARAMETERERROR, "提现信息不完善");
        withdrawApply.setRealName(bindAlipayAccountEntity.getRealName()).setAccount(bindAlipayAccountEntity.getAccount());

        if (! withdrawApplyService.insert(withdrawApply)) return new BaseResDto(Status.ERROR.setMessage("保存提现申请失败"));
        capitalMain.setDistributionMoney(NumberUtil.sub(capitalMain.getDistributionMoney(), withdrawApply.getIoMoney()));
        if (! capitalMainService.updateById(capitalMain)) return new BaseResDto(Status.ERROR.setMessage("修改用户资金账户失败"));
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public IntegralFlowResDto integralConsumeFlow(ReqMetaData param, String maijiToken) {
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.integralConsumeFlow,appUser is {}", JSON.toJSONString(appUser));
			return new IntegralFlowResDto(Status.PARAMETERERROR);
		}

		Integer start = (param.getPage() - 1) * param.getSize();

		List<CapitalMainLog> list = capitalMainLogMapper.getCapitalMainLogListByUserId(
				CommonIntValueEnum.CHANGE_TYPPE_REDUCE.getValue(), CommonIntValueEnum.CAPITAL_TYPE_INTEGRAL.getValue(),
				null,appUser.getUuId(),null,null, start, param.getSize());
		List<FinancialDetailsResData> listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>();
		for (CapitalMainLog capitalMainLog : list) {
			FinancialDetailsResData financialDetailsResData = new FinancialDetailsResData();
			BeanUtils.copyProperties(capitalMainLog, financialDetailsResData);
			financialDetailsResData.setRemark(FlowTypeEnum.getMsg(capitalMainLog.getRemark()));
			if (capitalMainLog.getRemark() != null
					&& FlowTypeEnum.ORDER_SUBMIT.getKey().equals(capitalMainLog.getRemark() )) {
				if (!StringUtils.isBlank(capitalMainLog.getRelevantId())) {
					ShopingOrder shopingOrder = shopingOrderMapper.selectById(capitalMainLog.getRelevantId());

					if (shopingOrder != null) {
						// 获取购物车记录集合
						EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
						wrapper.eq("order_id", shopingOrder.getUuId());
						List<ShopingOrderMiddleShopingCart> listShopingOrderMiddleShopingCart = shopingOrderMiddleShopingCartMapper
								.selectList(wrapper);

						List<String> cardIds = listShopingOrderMiddleShopingCart.stream()
								.map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
								.collect(Collectors.toList());

						List<String> stringNames = shopingCartMapper
								.selectList(new EntityWrapper<ShopingCart>().in("uu_id", cardIds)).stream()
								.map(shopingCart -> {
									Goods goods = goodsMapper.selectById(shopingCart.getGoodsId());
									return goods.getName();
								}).collect(Collectors.toList());

						financialDetailsResData.setGoodsNames(stringNames);
					}

				}
			} else if (capitalMainLog.getRemark() != null
					&& FlowTypeEnum.EXCHANGE_GOODS.getKey().equals(capitalMainLog.getRemark())) {
				ExchangeLog exchangeLog = exchangeLogMapper.selectById(capitalMainLog.getRelevantId());
				List<String> names = new ArrayList<String>();
				if(StringUtils.isBlank(exchangeLog.getGoodName())) {
					Goods goods = goodsMapper.selectById(exchangeLog.getDiscountCoupon());
					names.add(goods.getName());
				}else {
					names.add(exchangeLog.getGoodName());
				}

				financialDetailsResData.setGoodsNames(names);

			}
			listFinancialDetailsResData.add(financialDetailsResData);

		}

		IntegralFlowResDto financialDetailsResDto = new IntegralFlowResDto(Status.SUCCESS);

		financialDetailsResDto.setData(listFinancialDetailsResData);

		return financialDetailsResDto;
	}

	@Override
	public IntegralFlowResDto integralGainFlow(BaseDataReqDto<IntegralGainFlowReqData> param, String maijiToken) throws Exception {
		logger.info("CapitalMainLogServiceImpl.integralGainFlow,param is {}", JSON.toJSONString(param));
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.integralGainFlow,appUser is {}", JSON.toJSONString(appUser));
			new IntegralFlowResDto(Status.PARAMETERERROR);
		}
		Integer start = (param.getMetaData().getPage() - 1) * param.getMetaData().getSize();

		String time = param.getData().getEndTime();
		String endTime = TimeUtil.date2String(TimeUtil.getBefordayTime(TimeUtil.stringToDate(time, "yyyy-MM-dd"), 1, 0), "yyyy-MM-dd");
		
		List<CapitalMainLog> list = capitalMainLogMapper.getCapitalMainLogListByUserId(CommonIntValueEnum.CHANGE_TYPPE_ADD.getValue(),
				CommonIntValueEnum.CAPITAL_TYPE_INTEGRAL.getValue(),null, appUser.getUuId(),param.getData().getStartTime(),endTime, start, param.getMetaData().getSize());
		List<FinancialDetailsResData> listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>();
		for (CapitalMainLog capitalMainLog : list) {
			FinancialDetailsResData financialDetailsResData = new FinancialDetailsResData();
			BeanUtils.copyProperties(capitalMainLog, financialDetailsResData);
			financialDetailsResData.setRemark(FlowTypeEnum.getMsg(capitalMainLog.getRemark()));
			financialDetailsResData.setRemarkInt(capitalMainLog.getRemark());
			listFinancialDetailsResData.add(financialDetailsResData);

		}
		IntegralFlowResDto integralFlowResDto = new IntegralFlowResDto(Status.SUCCESS);
		integralFlowResDto.setData(listFinancialDetailsResData);
		
		return integralFlowResDto;
	}

	@Override
	public BaseDataResDto<List<FinancialDetailsResData>> balanceConsumeFlow(ReqMetaData param,String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.balanceConsumeFlow,param is {},maijiToken is {}", JSON.toJSONString(param),maijiToken);
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.balanceConsumeFlow,appUser is {}", JSON.toJSONString(appUser));
			new IntegralFlowResDto(Status.PARAMETERERROR);
		}
		EntityWrapper<CapitalMainLog> entityWrapper = new EntityWrapper<CapitalMainLog>();
		entityWrapper.eq("remark", FlowTypeEnum.BALANCE_PAY.getKey());
		entityWrapper.eq("user_id", appUser.getUuId());
		Page<CapitalMainLog> page = selectPage(new Page<>(param.getPage(), param.getSize()), entityWrapper);
		Map<String, List<CapitalMainLog>> map = page.getRecords().stream()
				.collect(Collectors.groupingBy(CapitalMainLog::getRelevantId));

		List<FinancialDetailsResData> listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>();
		for (String orderId : map.keySet()) {
			List<CapitalMainLog> listCapitalMainLog = map.get(orderId);
			FinancialDetailsResData financialDetailsResData = new FinancialDetailsResData();
			BeanUtils.copyProperties(listCapitalMainLog.get(0), financialDetailsResData);
			
			Double money = 0.0;
			for(CapitalMainLog capitalMainLog : listCapitalMainLog) {
				money += capitalMainLog.getChangeQuantity();
			}
			financialDetailsResData.setChangeQuantity(money);
			
			ShopingOrder shopingOrder = shopingOrderMapper.selectById(orderId);

			if (shopingOrder != null) {
				// 获取购物车记录集合
				EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
				wrapper.eq("order_id", shopingOrder.getUuId());
				List<ShopingOrderMiddleShopingCart> listShopingOrderMiddleShopingCart = shopingOrderMiddleShopingCartMapper
						.selectList(wrapper);

				List<String> cardIds = listShopingOrderMiddleShopingCart.stream()
						.map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
						.collect(Collectors.toList());

				List<String> stringNames = shopingCartMapper
						.selectList(new EntityWrapper<ShopingCart>().in("uu_id", cardIds)).stream().map(shopingCart -> {
							Goods goods = goodsMapper.selectById(shopingCart.getGoodsId());
							return goods.getName();
						}).collect(Collectors.toList());

				financialDetailsResData.setGoodsNames(stringNames);
			}

			listFinancialDetailsResData.add(financialDetailsResData);
		}
		BaseDataResDto<List<FinancialDetailsResData>> response = new BaseDataResDto<List<FinancialDetailsResData>>(Status.SUCCESS);
		response.setData(listFinancialDetailsResData);
		return response;
	}

	@Override
	public BaseDataResDto<List<FinancialDetailsResData>> reduceWeightFundConsumeFlow(ReqMetaData param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.reduceWeightFundConsumeFlow,param is {},maijiToken is {}", JSON.toJSONString(param),maijiToken);
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.reduceWeightFundConsumeFlow,appUser is {}", JSON.toJSONString(appUser));
			new IntegralFlowResDto(Status.PARAMETERERROR);
		}
		EntityWrapper<CapitalMainLog> entityWrapper = new EntityWrapper<CapitalMainLog>();
		entityWrapper.eq("remark", FlowTypeEnum.ORDER_SUBMIT.getKey());
		entityWrapper.eq("capital_type", FlowTypeEnum.FUND.getKey());
		entityWrapper.eq("user_id", appUser.getUuId());
		Page<CapitalMainLog> page = selectPage(new Page<>(param.getPage(), param.getSize()), entityWrapper);
		List<CapitalMainLog> listCapitalMainLog = page.getRecords();
			

		List<FinancialDetailsResData> listFinancialDetailsResData = new ArrayList<FinancialDetailsResData>();
		for (CapitalMainLog capitalMainLog : listCapitalMainLog) {
			FinancialDetailsResData financialDetailsResData = new FinancialDetailsResData();
			BeanUtils.copyProperties(capitalMainLog, financialDetailsResData);
			
			ShopingOrder shopingOrder = shopingOrderMapper.selectById(capitalMainLog.getRelevantId());

			if (shopingOrder != null) {
				// 获取购物车记录集合
				EntityWrapper<ShopingOrderMiddleShopingCart> wrapper = new EntityWrapper<ShopingOrderMiddleShopingCart>();
				wrapper.eq("order_id", shopingOrder.getUuId());
				List<ShopingOrderMiddleShopingCart> listShopingOrderMiddleShopingCart = shopingOrderMiddleShopingCartMapper
						.selectList(wrapper);

				List<String> cardIds = listShopingOrderMiddleShopingCart.stream()
						.map(shopingOrderMiddleShopingCart -> shopingOrderMiddleShopingCart.getShopingCartId())
						.collect(Collectors.toList());

				List<String> stringNames = shopingCartMapper
						.selectList(new EntityWrapper<ShopingCart>().in("uu_id", cardIds)).stream().map(shopingCart -> {
							Goods goods = goodsMapper.selectById(shopingCart.getGoodsId());
							return goods.getName();
						}).collect(Collectors.toList());

				financialDetailsResData.setGoodsNames(stringNames);
			}

			listFinancialDetailsResData.add(financialDetailsResData);
		}
		BaseDataResDto<List<FinancialDetailsResData>> response = new BaseDataResDto<List<FinancialDetailsResData>>(Status.SUCCESS);
		response.setData(listFinancialDetailsResData);
		return response;
	}

	@Override
	public BaseDataResDto<List<OrderReturnMoneyFlowResData>> getOrderReturnMoneyFlow(BaseDataReqDto<OrderReturnMoneyFlowReqData> param, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.getOrderReturnMoneyFlow,param is {},maijiToken is {}", JSON.toJSONString(param),maijiToken);
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.getOrderReturnMoneyFlow,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<List<OrderReturnMoneyFlowResData>>(Status.PARAMETERERROR);
		}
		Integer start = (param.getMetaData().getPage() - 1) * param.getMetaData().getSize();
		List<CapitalMainLog> list = capitalMainLogMapper.getCapitalMainLogListByUserId(
				CommonIntValueEnum.CHANGE_TYPPE_ADD.getValue(), CommonIntValueEnum.CAPITAL_TYPE_MONEY.getValue(),
				null,appUser.getUuId(),param.getData().getStartTime(),param.getData().getEndTime(), start, param.getMetaData().getSize());
		List<OrderReturnMoneyFlowResData> listOrderReturnMoneyFlowResData =  list.stream().map(capitalMainLog->{
			OrderReturnMoneyFlowResData orderReturnMoneyFlowResData = new OrderReturnMoneyFlowResData();
			BeanUtils.copyProperties(capitalMainLog, orderReturnMoneyFlowResData);
			if(FlowTypeEnum.SHAREORDERHELP.getKey().equals(capitalMainLog.getRemark())) {
				ShareOrderLog shareOrderLog = shareOrderLogMapper.selectById(capitalMainLog.getRelevantId());
				if(shareOrderLog != null && !StringUtils.isBlank(shareOrderLog.getOrderId()) ) {
					ShopingOrder shopingOrder = shopingOrderMapper.selectById(shareOrderLog.getOrderId());
					orderReturnMoneyFlowResData.setOrderNo(shopingOrder.getOrderNo());
				}
			}else if(!StringUtils.isBlank(capitalMainLog.getRelevantId())) {
				ShopingOrder shopingOrder = shopingOrderMapper.selectById(capitalMainLog.getRelevantId());
				orderReturnMoneyFlowResData.setOrderNo(shopingOrder.getOrderNo());
			}
			
			return orderReturnMoneyFlowResData;
			
		}).collect(Collectors.toList());
		BaseDataResDto<List<OrderReturnMoneyFlowResData>> response = new BaseDataResDto<List<OrderReturnMoneyFlowResData>>(Status.SUCCESS);
		response.setData(listOrderReturnMoneyFlowResData);
		return response;
	}

	@Override
	public BaseDataResDto<List<TaskListResData>> getTaskList(String maijiToken) throws Exception {
		logger.info("CapitalMainLogServiceImpl.getTaskList,maijiToken",maijiToken);
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.getTaskList,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<List<TaskListResData>>(Status.PARAMETERERROR);
		}
		List<TaskEntity> listTaskEntity = taskMapper.selectList(new EntityWrapper<>());
		List<Integer> remarks = new ArrayList<Integer>();
		remarks.add(FlowTypeEnum.SIGN_IN.getKey());
		remarks.add(FlowTypeEnum.PUBLISH.getKey());
		remarks.add(FlowTypeEnum.RETRANSMISSION.getKey());
		remarks.add(FlowTypeEnum.THUMBS.getKey());
		remarks.add(FlowTypeEnum.REVIEW.getKey());
		remarks.add(FlowTypeEnum.INVITE_REGISTER.getKey());
		remarks.add(FlowTypeEnum.SHOPPING_ORDER.getKey());
		EntityWrapper<CapitalMainLog> entityWrapper = 	new EntityWrapper<CapitalMainLog>();
		entityWrapper.in("remark", remarks);
		entityWrapper.eq("user_id", appUser.getUuId());
		entityWrapper.le("change_date", new Date());
		entityWrapper.ge("change_date", TimeUtil.date2String(new Date(), "yyyy-MM-dd"));
		 Map<Integer, List<CapitalMainLog>> map = capitalMainLogMapper.selectList(entityWrapper).stream().collect(Collectors.groupingBy(CapitalMainLog::getRemark));
		List<TaskListResData> list =  new ArrayList<TaskListResData>();
		  for(TaskEntity taskEntity : listTaskEntity) {
			  TaskListResData taskListResData = new TaskListResData();
			  BeanUtils.copyProperties(taskEntity, taskListResData);
			  if(map != null && map.get(taskEntity.getType()) != null && map.get(taskEntity.getType()).size() > 0) {
				  taskListResData.setIsFinish(1);//做过此任务
			  }else{
				  taskListResData.setIsFinish(0);//未做过
			  }
			  list.add(taskListResData);
			  
		  }
		  BaseDataResDto<List<TaskListResData>> baseDataResDto = new BaseDataResDto<List<TaskListResData>>(Status.SUCCESS);
		  baseDataResDto.setData(list);
		return baseDataResDto;
	}

	@Override
	public BaseDataResDto<List<BindWinthdrawAccountResData>> isBindWinthdrawAccount(List<Integer> types, String maijiToken) {
		logger.info("CapitalMainLogServiceImpl.isBindWinthdrawAccount,type is {},maijiToken", JSON.toJSONString(types),maijiToken);
		AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
		if (appUser == null) {
			logger.info("CapitalMainLogServiceImpl.isBindWinthdrawAccount,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<List<BindWinthdrawAccountResData>>(Status.PARAMETERERROR);
		}
		EntityWrapper<BindWithdrawAccountEntity> wrapper = new EntityWrapper<BindWithdrawAccountEntity>();
		wrapper.eq("user_id", appUser.getUuId());
		wrapper.in("type", types);
		Map<Integer,List<BindWithdrawAccountEntity>>  map = bindWithdrawAccountMapper.selectList(wrapper).parallelStream().collect(Collectors.groupingBy(BindWithdrawAccountEntity::getType));;
		
		List<BindWinthdrawAccountResData> list = new ArrayList<BindWinthdrawAccountResData>();
		for(Integer type :types) {
			BindWinthdrawAccountResData bindWinthdrawAccountResData = new BindWinthdrawAccountResData();
			bindWinthdrawAccountResData.setType(type);
			if(map.get(type) != null && map.get(type).size() >0 ) bindWinthdrawAccountResData.setIsBind(true);
			else bindWinthdrawAccountResData.setIsBind(false);
			list.add(bindWinthdrawAccountResData);
		}
		
		return new BaseDataResDto<List<BindWinthdrawAccountResData>>(Status.SUCCESS).setData(list);
	}

	@Override
	public BaseMetaResDto<List<CapitalMainLog>> findAllCapitalMainLogs(String userId, Integer capitalType, List<Date> changeDates, ReqMetaData metaData) {
        EntityWrapper<CapitalMainLog> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("user_id", userId);
        entityWrapper.eq("capital_type", capitalType);
        if (changeDates != null && changeDates.size() > 0) {
            entityWrapper.ge("change_date", changeDates.get(0));
            if (changeDates.size() > 1) entityWrapper.le("change_date", changeDates.get(1));
        }
        entityWrapper.orderBy("change_date", false);
        Page<CapitalMainLog> page = selectPage(new Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        List<CapitalMainLog> capitalMainLogs = page.getRecords().parallelStream().map(log ->
                log.setRemarkStr(FlowTypeEnum.getMsg(log.getRemark()))).collect(Collectors.toList());
        ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), page.getTotal());
        return new BaseMetaResDto<List<CapitalMainLog>>(Status.SUCCESS).setData(capitalMainLogs).setResMetaData(resMetaData);

    }

}
